package com.liumingtai.learn.shiro.utils;

import com.google.common.collect.Maps;

import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * Created by
 *
 * @author Honey
 */
public class DateUtil {
    private final static Map<String, String> weekConvertMap;

    static {
        weekConvertMap = Maps.newHashMap();
        weekConvertMap.put(DayOfWeek.MONDAY.name(), "星期一");
        weekConvertMap.put(DayOfWeek.TUESDAY.name(), "星期二");
        weekConvertMap.put(DayOfWeek.WEDNESDAY.name(), "星期三");
        weekConvertMap.put(DayOfWeek.THURSDAY.name(), "星期四");
        weekConvertMap.put(DayOfWeek.FRIDAY.name(), "星期五");
        weekConvertMap.put(DayOfWeek.SATURDAY.name(), "星期六");
        weekConvertMap.put(DayOfWeek.SUNDAY.name(), "星期日");
    }

    private static SimpleDateFormat sdf = new SimpleDateFormat();
    private static SimpleDateFormat _ISODate = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat _ISODateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    public static LocalDateTime asLocalDateTime(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    public static Date asDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }
    public static Date asDates(LocalDate localDate) {
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    public static synchronized Date parseDateDayFormat(String strDate) {
        String pattern = "yyyy-MM-dd";
        return parseDateFormat(strDate, pattern);
    }
    public static synchronized Date parseDateFormat(String strDate, String pattern) {
        SimpleDateFormat var2 = sdf;
        synchronized (sdf) {
            Date date = null;
            sdf.applyPattern(pattern);

            try {
                date = sdf.parse(strDate);
            } catch (Exception var6) {
                var6.printStackTrace();
            }

            return date;
        }
    }

    /**
     * @param date
     * @return 年月日 星期X 时间
     */
    public static String dateConvertSpecial(Date date) {
        String pattern = "{0} {1} {2}";
        LocalDateTime localDateTime = asLocalDateTime(date);
        String datePart = localDateTime.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
        String timePart = localDateTime.format(DateTimeFormatter.ofPattern("HH:mm:ss"));
        String weekPart = weekConvertMap.get(localDateTime.getDayOfWeek().name());
        return MessageFormat.format(pattern, datePart,weekPart, timePart);
    }

    public static String getTimeStr() {
        return _ISODate.format(new Date());
    }

    public static void main(String[] args) {
        System.out.println(dateConvertSpecial(new Date()));
    }

    public static String getLocalDateStr(Date date,String formatter) {

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatter);

        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
        String dateStr = dateTimeFormatter.format(localDateTime);

        return dateStr;
    }

    /**
     * 转换字符串时间为日期时间类型
     * @param dateStr
     * @return
     * @throws ParseException
     */
    public static Date parseStrToDate(String dateStr) throws ParseException {
        return _ISODateTime.parse(dateStr);
    }

    /**
     * 转换字符串时间为日期时间类型
     * @param date
     * @return
     * @throws ParseException
     */
    public static String formatDateToStr(Date date) {
        return _ISODateTime.format(date);
    }

    /**
     * 比较两个字符串时间类型的大小（日期时间格式为 "yyyy-MM-dd HH:mm:ss"）
     *
     * @param dateStrOne 日期时间一
     * @param dateStrTwo 日期时间二
     * @return int
     * @throws ParseException e
     */
    public static int compareTwoDateStr(String dateStrOne, String dateStrTwo) throws ParseException {
        return parseStrToDate(dateStrOne).compareTo(parseStrToDate(dateStrTwo));
    }

    /**
     * 获取之前的时间
     *
     * @param i 前多少天
     * @return
     */
    public static Date getBeforeDateOfNum(int i) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + i);
        return calendar.getTime();
    }

    /**
     * 获取指定日期之前的日期
     *
     * @param i 前多少天
     * @param assignDate 指定日期
     * @return
     */
    public static Date getBeforeDateOfNumByAssignDate(int i, Date assignDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(assignDate);
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + i);
        return calendar.getTime();
    }

    /**
     * 获取时间区间的天数
     *
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return
     */
    public static int getDayNumOfStartEndDate(Date startDate,Date endDate) {
        return (int) ((endDate.getTime() - startDate.getTime()) / (1000*3600*24));
    }
}
